import json

from PyQt5.QtWidgets import (
    QHBoxLayout,
    QVBoxLayout,
    QLabel,
    QDialog,
    QGridLayout,
    QPushButton,
    QFileDialog,
    QComboBox,
    QFrame,
    QGroupBox,
    QAbstractItemView,
    QTableWidgetItem,
    QTableWidget,
    QSpacerItem,
    QSizePolicy,
    QWidget,
)
from PyQt5.QtCore import pyqtSignal, pyqtSlot, Qt, QObject, QEvent
from PyQt5.QtGui import QPainter, QPen, QColor, QDoubleValidator
from pydantic import BaseModel, Field, field_validator
import gui.controls.envs as envs

# import gui.controls.envs as envs
from ..dlg_model_params import DlgModelParams
from ..dlg_params import DlgParams
from ..utils import Utils
from ..custom_widget import LineEditFloat, LineEditStr, LineEditInt, SelectBox
from .. import message_box as MBox


class CGridLayout(QGridLayout):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setAlignment(Qt.AlignTop)


class DlgMaterialSingle(QDialog):
    materialSingle_save_signal = pyqtSignal(object)
    _shown = False  # 类属性来跟踪对话框是否已显示
    _instance = None  # 用于保存对话框实例的类变量

    def __init__(self, parent=None, materialType="", materialName=""):
        super(DlgMaterialSingle, self).__init__(parent)

        self.currentRow = -1
        self.nameList = []
        self.isAdd = True

        self.widgetDict = {}

        self.setMinimumWidth(300)
        self.setMinimumHeight(200)

        self.materialType = materialType
        self.materialName = materialName
        self.setWindowTitle(materialType)
        data = self.getData()
        self.allData = data.get("data")
        self.lastId = data.get("lastId")
        if not self.lastId or self.lastId < 0:
            self.lastId = 0
        if not self.allData:
            self.allData = []

        self.data = {}
        if self.materialType == "复合材料单层板":
            self.data = {
                "材料名称": "",
                "E1": None,
                "E2": None,
                "Nu12": None,
                "G12": None,
                "G13": None,
                "G23": None,
                "id": None,
            }
        elif self.materialType == "蜂窝芯子":
            self.data = {
                "材料名称": "",
                "壁厚t": None,
                "边长l": None,
                "密度ρ": None,
                "Es": None,
                "Gs": None,
                "id": None,
            }
        elif self.materialType == "胶层":
            self.data = {
                "材料名称": "",
                "E/Enn": None,
                "G1/Enn": None,
                "G2/Enn": None,
                "id": None,
            }

        for row, item in enumerate(self.allData):
            if materialName == item.get("材料名称"):
                self.data = item
                self.currentRow = row
                self.isAdd = False
                continue
            self.nameList.append(item.get("材料名称"))

        self.layout = QVBoxLayout(self)
        self.gridLayout = CGridLayout()
        self.updateUI(self.gridLayout)
        # self.layout.addStretch()
        self.layout.addLayout(self.gridLayout)
        btnLayout = QHBoxLayout()
        btnLayout.setContentsMargins(10, 15, 10, 0)  # 左, 上, 右, 下
        btnLayout.setAlignment(Qt.AlignCenter)
        addBtn = QPushButton("确认")
        cancelBtn = QPushButton("取消")
        btnLayout.addWidget(addBtn)
        btnLayout.addWidget(cancelBtn)
        self.layout.addLayout(btnLayout)

        addBtn.clicked.connect(self.on_addBtn_clicked)
        cancelBtn.clicked.connect(self.reject)
        self.setLayout(self.layout)

    def getData(self):
        if self.materialType == "复合材料单层板":
            data = Utils.read_json("data/ipimas/uis/compositePly.json")
        elif self.materialType == "蜂窝芯子":
            data = Utils.read_json("data/ipimas/uis/honeycombCore.json")
        elif self.materialType == "胶层":
            data = Utils.read_json("data/ipimas/uis/adhesiveLayer.json")
        return data

    def refData(self):
        data = self.getData()
        self.allData = data.get("data")
        self.lastId = data.get("lastId")

        if not self.lastId or self.lastId < 0:
            self.lastId = 0
        if not self.allData:
            self.allData = []

        # self.data = {}
        # if self.materialType == "复合材料单层板":
        #     self.data = {"材料名称":"","E1":None,"E2":None,"Nu12":None,"G12":None,"G13":None,"G23":None,"id":None}
        # elif self.materialType == "蜂窝芯子":
        #     self.data = {"材料名称":"","壁厚t":None,"边长l":None,"密度ρ":None,"Es":None,"Gs":None,"id":None}
        # elif self.materialType == "胶层":
        #     self.data = {"材料名称":"","E/Enn":None,"G1/Enn":None,"G2/Enn":None,"id":None}
        for row, item in enumerate(self.allData):
            if not self.isAdd:
                if self.widgetDict["id"] == item.get("id"):
                    self.currentRow = row
                    continue
            self.nameList.append(item.get("材料名称"))

    @classmethod
    def show(cls, parent=None, materialType="", materialName=""):
        if cls._shown:
            cls._instance.activateWindow()
            cls._instance.raise_()
            # return cls._instance
        else:
            # cls._shown = True
            cls._instance = cls(
                parent, materialType, materialName
            )  # 创建新实例并传入parent
            cls._instance.setParent(parent)  # 设置父窗口
            QDialog.show(cls._instance)  # 直接调用QDialog的show方法
            cls._shown = True
            return cls._instance

    def updateUI(self, gridLayout):
        for row, (key, value) in enumerate(self.data.items()):
            if key == "材料类型":
                continue
            if key == "材料名称":
                label = QLabel("名称")
            else:
                label = QLabel(key)
            gridLayout.addWidget(label, row, 0)
            if row == 0:
                self.widgetDict[key] = LineEditStr(data={"require": True, "title": key})
            else:
                self.widgetDict[key] = LineEditFloat()
            if value:
                self.widgetDict[key].setValue(value)
            gridLayout.addWidget(self.widgetDict[key], row, 1)
            if key == "id":
                label.setVisible(False)
                self.widgetDict[key].setVisible(False)
                if self.isAdd and self.lastId >= 0:
                    self.widgetDict[key].setValue(self.lastId + 1)
                    # if self.type == "add":
                    self.widgetDict["材料名称"].setText(
                        self.materialType + "_" + str(int(self.lastId + 1))
                    )

    def on_addBtn_clicked(self):
        res = {}
        for k, v in self.widgetDict.items():
            if v.getRequire() and not v.getValue():
                MBox.warning(f"请输入{v.getLable()}！")
                return
            # if v.getValue() == None:
            #     QMessageBox.warning(self, "警告", "请输入所有必填项！")
            #     return
            res[k] = v.getValue()
        self.refData()

        for name in self.nameList:
            if res["材料名称"] == name:
                MBox.warning("该名称已存在！")
                return
        if self.isAdd:
            self.allData.append(res)
            lastId = self.lastId + 1
        else:
            lastId = self.lastId
            self.allData.pop(self.currentRow)  # 移除元素3
            self.allData.insert(self.currentRow, res)

        data = {"data": self.allData, "lastId": lastId}
        if self.materialType == "复合材料单层板":
            file = "data/ipimas/uis/compositePly.json"
            Utils.write_json(file, data)
            if hasattr(envs, "ipimas_updateCompositePly"):
                envs.ipimas_updateCompositePly()
        elif self.materialType == "蜂窝芯子":
            file = "data/ipimas/uis/honeycombCore.json"
            Utils.write_json(file, data)
            if hasattr(envs, "ipimas_updateHoneycombCore"):
                envs.ipimas_updateHoneycombCore()
        elif self.materialType == "胶层":
            file = "data/ipimas/uis/adhesiveLayer.json"
            Utils.write_json(file, data)
            if hasattr(envs, "ipimas_updateAdhesiveLayer"):
                envs.ipimas_updateAdhesiveLayer()
        self.close()
        filtered_data = [
            {k: v for k, v in item.items() if k != "id"} for item in self.allData
        ]
        self.materialSingle_save_signal.emit(filtered_data)

    def closeEvent(self, event):
        DlgMaterialSingle._shown = False  # 使用类名访问类属性
        DlgMaterialSingle._instance = None  # 清除实例引用
        event.accept()
